package com.moco.launcher.play;

import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.util.Log;

import com.moco.launcher.link.LinkManager;
import com.oazon.common.TaskHelper;
import com.oazon.moco.link.core.LinkSDK;
import com.oazon.moco.serialport.SerialSend;

public class MocoPlayerClient {
	private IMocoPlayerService mPlayService = null;
	private Context mContext = null;

	public static final Integer OPEN_VIDEA = 1;
	private static final String TAG = "MocoPlayerClient";
	private volatile static MocoPlayerClient instance;
	// private static boolean SHIFT_flag = false;
	private static int volume;
	private final int volumeDelay = 500; // ms
	private final float volumeTotalTime = 6.0f;
	private Timer volumeTimer = null;

	/** Returns singleton class instance */
	public static MocoPlayerClient getInstance() {
		if (instance == null) {
			synchronized (MocoPlayerClient.class) {
				if (instance == null) {
					instance = new MocoPlayerClient();
				}
			}
		}
		return instance;
	}
	private static final String PLAYER_SERVICE = "com.moco.launcher.play.MocoPlayerService";
	private static final String PLAYER_SERVICE_STARTACTION = "android.intent.action.StartPlayerService";

	private Handler mocoPlayerHandler = null;
	private HandlerThread mocoPlayerHandlerThread = null;

	private MocoPlayerClient() {
		mocoPlayerHandlerThread = new HandlerThread("mocoPlayerHandler");
		mocoPlayerHandlerThread.start();
		mocoPlayerHandler = new Handler(mocoPlayerHandlerThread.getLooper()) {
			@Override
			public void handleMessage(Message msg) {
				if (msg.what == OPEN_VIDEA) {
					handPlayItem((MusicItemInfo) msg.obj);
				}
			}
		};
	}

	public void init(Context context) {
		mContext = context;
	}

	public void bindPlayService() {
		Intent intent = new Intent(PLAYER_SERVICE);
		intent.setAction(PLAYER_SERVICE_STARTACTION);
		if (mConnection == null) {
			mConnection = new ServiceConnection() {
				public void onServiceConnected(ComponentName className,
						IBinder service) {
					mPlayService = IMocoPlayerService.Stub.asInterface(service);
					Log.d(TAG, "BIND TO the player service= " + mPlayService);
				}

				public void onServiceDisconnected(ComponentName className) {
					mPlayService = null;
					Log.d(TAG, "UNBIND TO the player service");
				}
			};
		}
		mContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
	}

	public void startPlayService() {
		Intent intent = new Intent(PLAYER_SERVICE);
		intent.setAction(PLAYER_SERVICE_STARTACTION);
		mContext.startService(intent);
	}

	private ServiceConnection mConnection = new ServiceConnection() {
		public void onServiceConnected(ComponentName className, IBinder service) {
			mPlayService = IMocoPlayerService.Stub.asInterface(service);
			Log.d(TAG, "BIND TO the player service= " + mPlayService);
		}

		public void onServiceDisconnected(ComponentName className) {
			mPlayService = null;
			Log.d(TAG, "UNBIND TO the player service");
		}
	};

	public long getCurrentPosition() {
		long pos = -1;
		if (mPlayService != null) {
			try {
				pos = mPlayService.getCurrentPosition();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		return pos;
	}

	public long getDuration() {
		long duration = -1;
		if (mPlayService != null) {
			try {
				duration = mPlayService.getDuration();
			} catch (RemoteException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return duration;
	}

	public void seekTo(long msec) {
		if (mPlayService != null) {
			try {
				mPlayService.seekTo(msec);
			} catch (RemoteException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	public void register(OnStatusChangeCallback cb) {
		if (mPlayService != null) {
			try {
				mPlayService.registerStatusChangeCallback(cb);
			} catch (RemoteException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	public void unregister(OnStatusChangeCallback cb) {
		if (mPlayService != null) {
			try {
				mPlayService.unregisterStatusChangeCallback(cb);
			} catch (RemoteException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	public void playList(List<MusicItemInfo> list) {
		// Log.d(TAG, "playList......" + list.toString());
		if (mPlayService != null) {
			Log.d(TAG, "mPlayService != null");
			try {
				// mPlayService.test();
				mPlayService.play(list);
			} catch (RemoteException e) {
				// TODO Auto-generated catch block
				Log.d(TAG, "RemoteException......" + e.getMessage());
				e.printStackTrace();
			}
		}
	}

	public void playItem(MusicItemInfo item) {
		mocoPlayerHandler.removeMessages(MocoPlayerClient.OPEN_VIDEA);
		Log.d("PlayListManage", "playItem==" + item.getTitle());
		Message message = mocoPlayerHandler.obtainMessage();
		message.what = MocoPlayerClient.OPEN_VIDEA;
		message.obj = item;
		mocoPlayerHandler.sendMessageDelayed(message, 500);
	}

	private void handPlayItem(MusicItemInfo item) {
		Log.d(TAG, "handPlayItem");
		if (mPlayService != null) {
			try {
				volumeFadein();
				mPlayService.playItem(item);
			} catch (RemoteException e) {
				e.printStackTrace();
			}
		}
	}

	public void stop() {
		if (mPlayService != null) {
			try {
				mPlayService.stop();
			} catch (RemoteException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	public boolean isPlaying() {

		boolean bPlay = false;
		if (mPlayService != null) {
			try {
				bPlay = mPlayService.isPlaying();
			} catch (RemoteException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		return bPlay;
	}

	public void pause() {

		iPause(true,false);
	}

	public void iPause(boolean notifyAll,boolean notNeedFadeOut) {
		if (mPlayService != null) {

			if (notifyAll) {
				// TODO 通知各通信暂停播放
				LinkManager.getInstance().pause();
			}
			
     
            	// 增加声音过渡效果 15.6.5
			if(notNeedFadeOut==true){
				try {
					//voice no need fadeout
					mPlayService.pause();
				} catch (RemoteException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}else{
				stopTimer();
				volumeFadeOut();
			}
			
            
		}
	}

	public void start() {
		iStart(true);
	}

	public boolean isAdjustVoluming() {
		return volumeTimer == null ? false : true;
	}

	public void stopTimer() {
		if (isAdjustVoluming()) {
			Log.d(TAG, "stopTimer");
			if(volumeTimer!=null){
				volumeTimer.cancel();
				volumeTimer = null;
			}
			
		}
	}

	public void iStart(boolean notifyAll) {
		if (mPlayService != null) {
			try {
				if (notifyAll) {
					// TODO 通知各通信暂停播放
					LinkManager.getInstance().play();
				}

				mPlayService.start();
				// 增加声音过渡效果taylor 15.6.5
				// if (SHIFT_flag) {
				stopTimer();
				volume = 0;
				volumeFadein();
				// SHIFT_flag = false;
				// }else{
				// SerialSend.getInstance().sendVolume(LinkSDK.curVolume);
				// Log.i(TAG, "有暂停状态到播放状态声音突然增大");
				// }
			} catch (RemoteException e) {
				e.printStackTrace();
			}
		}
	}

	public void playNext() {
		if (mPlayService != null) {
			try {
				mPlayService.playNext();
			} catch (RemoteException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	public void playCurrent() {
		if (mPlayService != null) {
			try {
				mPlayService.playCurrent();
			} catch (RemoteException e) {
				e.printStackTrace();
			}
		}
	}

	public void setLoopMode(long mode) {
		if (mPlayService != null) {
			try {
				mPlayService.setLoopMode(mode);
				;
			} catch (RemoteException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	public void playPrev() {
		if (mPlayService != null) {
			try {
				mPlayService.playPrev();
			} catch (RemoteException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	public String getCurrentId() {
		String id = null;
		if (mPlayService != null) {
			try {
				id = mPlayService.getCurrentId();
			} catch (RemoteException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		return id;
	}

	public long getAudioSessionId() {
		long sessionId = 0;
		if (mPlayService != null) {
			try {
				sessionId = mPlayService.getAudioSessionId();
			} catch (RemoteException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		return sessionId;
	}

	public void setVolume(int left, int right) {
		if (mPlayService != null) {
			try {
				mPlayService.setVolume(left, right);
			} catch (RemoteException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	public void setPlayList(List<MusicItemInfo> list) {
		if (mPlayService != null) {
			try {
				mPlayService.setPlayList(list);
			} catch (RemoteException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	public void unbindService() {
		if (mConnection != null)
			mContext.unbindService(mConnection);
		mConnection = null;
	}

	private synchronized Timer creatVolumeTimer() {
		if (volumeTimer == null) {
			volumeTimer = new Timer();
		}
		return volumeTimer; 
	}

	private synchronized void stopVolumeTimer() {
		if (volumeTimer != null) {
			volumeTimer.cancel();
			volumeTimer = null;
		}
	}

	/*
	 * 播放状态由暂停到播放 声音逐渐变化到最大
	 */

	private void volumeFadein() {

		volumeTimer = creatVolumeTimer();
		final int step = getStep(volume, LinkSDK.curVolume);
		TimerTask timertask = new TimerTask() {

			@Override
			public void run() {
				if (volume < LinkSDK.curVolume) {
					volume = volume + step;
					SerialSend.getInstance().sendVolume(volume);
					Log.i(TAG, "volumeFadein---volume==" + volume);
				} else {
					if (volume != LinkSDK.curVolume) {
						volume = LinkSDK.curVolume;
						SerialSend.getInstance().sendVolume(volume);
						Log.i(TAG, "volumeFadein---volume==" + volume);
					}
					stopVolumeTimer();
					Log.i(TAG, "volumeTimer cancel");
				}

			}
		};

		volumeTimer.schedule(timertask, 0, volumeDelay);
	}

	private synchronized int getStep(int volume, int targetVolume) {
		int result = Math.abs(volume - targetVolume) / (int) volumeTotalTime;
		float temp = Math.abs(volume - targetVolume) / volumeTotalTime;
		if (result == 0) {
			result = 1;
		}
		if (temp <= 0.5f)
			result = 1;
		if ((temp % (int) temp) > 0.5)
			result = (int) temp + 1;
		Log.d(TAG, "step " + result + " volume:" + volume + " targetVolume: "
				+ targetVolume + " temp:" + temp + " ");
		return result;
	}

	/*
	 * 播放状态由播放到暂停，声音逐渐变小  15.6.5
	 */
	private void volumeFadeOut() {
		volumeTimer = creatVolumeTimer();
		final int step = getStep(volume, 1);
		TimerTask timertask = new TimerTask() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
				if (1 < volume) {
					volume = volume - step;
					SerialSend.getInstance().sendVolume(volume);
					Log.i(TAG, "volumeFadein---volume==" + volume);
				} else {
					try {
						mPlayService.pause();
					} catch (RemoteException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					// SHIFT_flag = true;
					if (volume != 1) {
						volume = 1;
						SerialSend.getInstance().sendVolume(volume);
						Log.i(TAG, "volumeFadein---volume==" + volume);
					}
					//暂停完成之后音量调整为原来的音量				
					TaskHelper.exec(new Runnable() {
						@Override
						public void run() {
							// TODO Auto-generated method stub
							Log.i(TAG, "暂停完成之后音量调整为原来的音量");
							SerialSend.getInstance().sendVolume(LinkSDK.curVolume);
						}
					}, 1000);
					stopVolumeTimer();
					Log.i(TAG, "volumeTimer cancel");
				}
			}
		};

		volumeTimer.schedule(timertask, 0, volumeDelay);
	}

}
